function varargout = TLPreprocessorifDlg(action, varargin)

% TL_PREPROCESSORIF_DLG manages the user interface for TargetLink Preprocessor If block
%
% SYNTAX dlgInfo = TLPreprocessorifDlg('GetDlgInfo');
%   gets dialog info of TargetLink Preprocessor If block
%
%   INPUT ARGUMENTS
%   -/-      
%
%   OUTPUT ARGUMENTS
%   dlgInfo     dialog information contains pageNames etc.
%
% SYNTAX [sheetDims, ctrlPos] = TLPreprocessorifDlg('CtrlPositions', pageName, commonGeom, dlgInfo, sheetDims);
%   calculates the control positions of all controls of dialog page: <pageName>
%
%   INPUT ARGUMENTS
%   pageName        name of current page
%   commonGeom      common geometry data
%   dlgInfo         dialog information contains pageNames etc.
%   sheetDims       dimension of sheet
%
%   OUTPUT ARGUMENTS
%   sheetDims       modified dimension of sheet
%   ctrlPos         positions of controls
%
% SYNTAX dlgdata = TLPreprocessorifDlg('Create', pageName, dlgfig, dlgdata);
%   creates all controls of dialog page: <pageName>
%
%   INPUT ARGUMENTS
%   pageName        name of current page
%   dlgfig          figure handle
%   dlgdata         dialog data
%
%   OUTPUT ARGUMENTS
%   dlgdata         modified dialog data
%
% SYNTAX [dlgdata,bModified] = TLPreprocessorifDlg('Manage', pageName, dlgfig, dlgdata, pageAction);
%   manages all actions of dialog page: <pageName>
%
%   INPUT ARGUMENTS
%   pageName        name of current page
%   dlgfig          figure handle
%   dlgdata         dialog data
%   pageAction      modified control of current page
%
%   OUTPUT ARGUMENTS
%   dlgdata         modified dialog data
%   bModified       flag = 1, if dialog data are modified, =0 otherwise
%
% SYNTAX dlgdata = TLPreprocessorifDlg('Update', dlgfig, dlgdata, pageNum);
%   updates all controls of dialog page: <pageNum>
%
%   INPUT ARGUMENTS
%   dlgfig          figure handle
%   dlgdata         dialog data
%   pageNum         number of current page
%
%   OUTPUT ARGUMENTS
%   dlgdata         modified dialog data
%
% SYNTAX TLPreprocessorifDlg('Apply', dlgfig, dlgdata);
%   writes current blockdata to block and DD
%
%   INPUT ARGUMENTS
%   dlgfig      handle for dialog figure
%   dlgdata     dialog data
%
%   OUTPUT ARGUMENTS
%   - / -


% Author(s): D. Andoleit, T. Pietzsch
% $RCSfile: TLPreprocessorifDlg.m $
% $ProjectName: e:/ARC/Components/HostSW/SimulinkBlocksets/TLBlocksets/CommonBlockset/CommonBlockset_SimBlocksUI/Sources/MSrc/project.pj $
% $Revision: 1.12 $
% $Date: 2011/03/17 12:05:11MEZ $
%
% Copyright ?2011 dSPACE GmbH. All rights reserved.


switch action,
    case 'GetDlgInfo'
        hBlock = varargin{1};
        dlgInfo = tl_get_dlginfodefaults('tlsim');
        titleName = 'Preprocessor If';
        pathinfo = tl_pathinfo(hBlock);
        dlgInfo.title = sprintf('TargetLink %s: %s', titleName, pathinfo.shortDisplayName);
        % return structure holding the names of tabs
        dlgInfo.pageNames = {
            'Parameter';
            'Documentation'};
        varargout{1} = dlgInfo;
        varargout{2} = get_tlcg_data(hBlock);

    case 'CtrlPositions'
        % identify input arguments
        pageName     = varargin{1};
        commonGeom   = varargin{2};
        sheetDims    = varargin{4};
        switch pageName,
            case 'Parameter'
                [sheetDims,ctrlPos] = FcnParameterCtrlPosition(commonGeom);

            case 'Documentation'
                bCodeComment = 1;
                [sheetDims,ctrlPos] = TLManageDocCtrls(...
                    'ctrlpos', commonGeom, sheetDims, bCodeComment, 0);
                
            otherwise
                error(['Nonexistent page "' action '"']);
        end
        varargout{1} = sheetDims;
        varargout{2} = ctrlPos;

    case 'Create'
        % identify input arguments
        pageName = varargin{1};
        dlgfig   = varargin{2};
        dlgdata  = varargin{3};
        pageNum  = find(strcmp(pageName, dlgdata.pageNames));

        switch pageName
            case 'Parameter'
                dlgdata = FcnCreateParameterPage(pageNum, dlgfig, dlgdata);

            case 'Documentation'
                dlgdata = TLManageDocCtrls('create', pageNum, dlgfig, dlgdata);

            otherwise
                error(['Nonexistent page  "' action '"']);
        end
        dlgdata.pageData{pageNum}.ctrlPos = [];
        varargout{1} = dlgdata;

    case 'Manage'
        % identify input arguments
        pageName   = varargin{1};
        dlgfig     = varargin{2};
        dlgdata    = varargin{3};
        pageAction = varargin{4};
        pageNum    = find(strcmp(pageName,dlgdata.pageNames));
        switch pageName
            case 'Parameter'
                [dlgdata, bModified] = FcnManageParameterPage(dlgdata, pageAction);
                
            case 'Documentation'
                [dlgdata, bModified] = ...
                    TLManageDocCtrls('callback', pageNum, dlgfig, dlgdata, pageAction);

            otherwise
                error(['Nonexistent page "' action '"']);
        end
        varargout{1} = dlgdata;
        varargout{2} = bModified;

    case 'ManageSystemIcons',
        dlgfig     = varargin{1};
        dlgdata    = varargin{2};
        pageAction = varargin{3};
        [dlgdata, bModified] = FcnManageSystemIcons(dlgfig,dlgdata,pageAction);
        varargout{1} = dlgdata;
        varargout{2} = bModified;

    case 'Update'
        dlgfig = varargin{1};
        dlgdata = varargin{2};
        pageNum = varargin{3};
        if pageNum == 1
            % Parameter page
            dlgdata = FcnUpdateParameterPage(dlgfig,dlgdata,pageNum);
        elseif pageNum == 2
            % documentation page
            TLManageDocCtrls('update', pageNum, dlgfig, dlgdata);
        end
        varargout = {dlgdata};

    case 'Apply'
        dlgdata  = varargin{2};
        bClose   = varargin{3};
        [dlgdata, bClose] = tl_apply_blockdata(dlgdata, bClose);
        varargout{1} = dlgdata;
        varargout{2} = bClose;

    otherwise
        error(['Invalid action "' action '"']);

end


%-----------------------------------------------------------------------------------------
% FcnManageSystemIcons manage actions of toolbar icons
%
% INPUT ARGUMENTS
%   dlgfig      handle for dialog figure
%   dlgdata     dialog data
%   action      action at one control of current page
%
% OUTPUT ARGUMENTS
%   dlgdata     modified dialog data
%   bModified   flag = 1, if dialog data are modified, =0 otherwise
%-----------------------------------------------------------------------------------------
function [dlgdata, bModified] = FcnManageSystemIcons(dlgfig, dlgdata, action) %#ok

bModified = false;
switch action
    case 'EditCode'
        % look for associated production code file
        [codefile,blockstr] = get_codefile(dlgdata.model);
        if ~isempty(codefile)
            codeedit(codefile,blockstr);
        end

    case 'ViewCode'
        tl_create_links_to_model('ShowComputation',dlgdata.model, 'output');

    otherwise
        error('Invalid callback');

end % switch(action)


%-----------------------------------------------------------------------------------------
% FcnParameterCtrlPosition calculates positions for all controls on parameter page
%
% INPUT ARGUMENTS
%   commonGeom      common geometrie information
%
% OUTPUT ARGUMENTS
%   sheetDims       modified dimension of sheet
%   ctrlPos         positions of controls
%
% HINT:
% Positions are calculated from the bottom left of the figure to avoid
% dependencies on figure size
%-----------------------------------------------------------------------------------------
function [sheetDims,ctrlPos] = FcnParameterCtrlPosition(commonGeom)

% Get the sizes of the edit fields, checkboxes, buttons and labels (last is
% determined from the longest label).
strings_and_styles = {
    'Elseif expression (comma-separated list for more than one elseif expression: ',   'text'; ...
    repmat('m',1,30),           'edit'; ...
    'Show else condition',      'checkbox'; ...
    '+',                        'pushbutton'};

[labelSize, ...
    editSize, ...
    checkboxSize, ...
    counterButtonSize] = ds_get_uicontrol_sizes(commonGeom,strings_and_styles);

% Get the page partitioning and row/column spacing.
widths = labelSize(1);
[col,colWidth,colDelta,rowDelta] = ds_get_gui_columns(widths,commonGeom);

% Edit Width is max of Edit width and Label width
editSize(1) = max(editSize(1), labelSize(1));

% Adjustment of width of uP/Down Buttons and "number of inputs" edit field
counterButtonSize = counterButtonSize * diag([1,0.5]);
numInputEditSize = editSize;
numInputEditSize(1) = editSize(1) - counterButtonSize(1) - colDelta/3;

% All groupboxes in this page have the same width
groupboxWidth = sum(colWidth) + 2 * commonGeom.frameSideEdgeBuffer;

% Position of Condition Properties groupbox.
conditionsGroupboxHeight = ...
    commonGeom.frameTopEdgeBuffer ...
    + checkboxSize(2) ...
    + 4 * (editSize(2) + rowDelta) ...
    + 4 * (labelSize(2)) ...
    + commonGeom.frameBottomEdgeBuffer;
cx = commonGeom.figSideEdgeBuffer + commonGeom.sheetSideEdgeBuffer;
cy = commonGeom.bottomSheetOffset + commonGeom.sheetBottomEdgeBuffer;
ctrlPos.conditionsGroupbox = [cx,cy,groupboxWidth,conditionsGroupboxHeight];

% Postion of "Show else condition" checkbox
cx = col(1);
cy = commonGeom.frameBottomEdgeBuffer;
ctrlPos.showElseCheckbox = [cx cy checkboxSize];

% Postion of Elseif expression Edit and label
cx = col(1);
cy = cy + rowDelta + checkboxSize(2);
ctrlPos.elseIfEdit = [cx cy editSize];
cy = cy + editSize(2);
ctrlPos.elseIfLabel = [cx cy labelSize];

% Postion of If expression Edit and label
cx = col(1);
cy = cy + rowDelta + labelSize(2);
ctrlPos.ifEdit = [cx cy editSize];
cy = cy + editSize(2);
ctrlPos.ifLabel = [cx cy labelSize];

% Postion of Mode Edit and label
cx = col(1);
cy = cy + rowDelta +  labelSize(2);
ctrlPos.modePopup = [cx cy editSize];
cy = cy + editSize(2);
ctrlPos.modeLabel = [cx cy labelSize];

% Postion of Number of inputs expression Edit and label
cx = col(1);
cy = cy + rowDelta +  labelSize(2);
ctrlPos.numInputEdit = [cx cy numInputEditSize];
cx = cx + numInputEditSize(1) + colDelta/3;
dy = commonGeom.editHeight / 2;
ctrlPos.numInputUpButton = [cx (cy + dy)  counterButtonSize];
ctrlPos.numInputDownButton = [cx cy counterButtonSize];
cx = col(1);
cy = cy + editSize(2);
ctrlPos.numInputLabel = [cx cy labelSize];

% Width and height of page
width = groupboxWidth + 2*commonGeom.sheetSideEdgeBuffer;
height = ...
    + ctrlPos.conditionsGroupbox(4) ...
    + commonGeom.textHeight + ...
    commonGeom.sheetBottomEdgeBuffer;
sheetDims = [width height];


%-----------------------------------------------------------------------------------------
% FcnCreateParameterPage creates the figure window
%
% INPUT ARGUMENTS
%   pageNum     number of current page
%   dlgfig      handle for dialog figure
%   dlgdata     dialog data
%
% OUTPUT ARGUMENTS
%   dlgdata     modified dialog data
%-----------------------------------------------------------------------------------------
function dlgdata = FcnCreateParameterPage(pageNum,dlgfig,dlgdata)

ctrlPos = dlgdata.pageData{pageNum}.ctrlPos;

% Conditions groupbox
Children.conditionsGroupbox = uipanel( ...
    'Parent',            dlgfig, ...
    'Title',            {'Conditions'}, ...
    'Units',            'pixels', ...
    'Position',          ctrlPos.conditionsGroupbox);

Children.showElseCheckbox  = uicontrol( ...
    'Parent',       Children.conditionsGroupbox, ...
    'Style',        'checkbox', ...
    'String',       'Show else condition', ...
    'Position',     ctrlPos.showElseCheckbox  );

Children.elseIfLabel  = uicontrol( ...
    'Parent',       Children.conditionsGroupbox, ...
    'Style',        'text', ...
    'String',       'Elseif expression (comma-seperated list for more than one elseif expression):', ...
    'Position',     ctrlPos.elseIfLabel);

Children.elseIfEdit  = uicontrol( ...
    'Parent',       Children.conditionsGroupbox, ...
    'Style',        'edit', ....
    'Position',     ctrlPos.elseIfEdit  );

Children.ifLabel  = uicontrol( ...
    'Parent',       Children.conditionsGroupbox, ...
    'Style',        'text', ...
    'String',       'If expression (for example u1 == 1)', ...
    'Position',     ctrlPos.ifLabel);

Children.ifEdit  = uicontrol( ...
    'Parent',       Children.conditionsGroupbox, ...
    'Style',        'edit', ....
    'Position',     ctrlPos.ifEdit  );

Children.modeLabel  = uicontrol( ...
    'Parent',       Children.conditionsGroupbox, ...
    'Style',        'text', ...
    'String',       'Mode', ...
    'Position',     ctrlPos.modeLabel);

Children.modePopup   = uicontrol( ...
    'Parent',       Children.conditionsGroupbox, ...
    'String',        {'#if'}, ...
    'Style',        'popupmenu', ....
    'Position',     ctrlPos.modePopup   );

Children.numInputLabel  = uicontrol( ...
    'Parent',        Children.conditionsGroupbox, ...
    'Style',        'text', ...
    'String',       'Number of inputs', ...
    'Position',     ctrlPos.numInputLabel);

Children.numInputEdit  = uicontrol( ...
    'Parent',       Children.conditionsGroupbox, ...
    'Style',        'edit', ....
    'Position',     ctrlPos.numInputEdit  );

Children.numInputDownButton = uicontrol( ...
    'Parent',       Children.conditionsGroupbox, ...
    'Style',        'pushbutton', ...
    'String',       '-', ...
    'Position',     ctrlPos.numInputDownButton);

Children.numInputUpButton = uicontrol( ...
    'Parent',       Children.conditionsGroupbox, ...
    'Style',        'pushbutton', ...
    'String',       '+', ...
    'Position',     ctrlPos.numInputUpButton);

dlgdata.pageData{pageNum}.children = Children;

%-----------------------------------------------------------------------------------------
% FcnManageParameterPage manages control actions of parameter page
%
% INPUT ARGUMENTS
%   dlgdata     dialog data
%   pageAction  action at one control of current page
%
% OUTPUT ARGUMENTS
%   dlgdata     modified dialog data
%   bModified   flag = 1, if dialog data are modified, =0 otherwise
%-----------------------------------------------------------------------------------------
function [dlgdata, bModified] = FcnManageParameterPage(dlgdata, pageAction)

% prepare needed data
pageNum   = 1;
bModified = 0;
Children  = dlgdata.pageData{pageNum}.children;
data      = dlgdata.data;

switch pageAction
    case 'showElseCheckbox'
        data.showelse = get(Children.showElseCheckbox, 'Value');
        bModified = 1;

    case 'elseIfEdit'
        elseIfStr = tl_deblank(get(Children.elseIfEdit, 'String'),2);
        data.elseifexpressions = elseIfStr;
        bModified = 1;

    case 'ifEdit'
        ifStr = tl_deblank(get(Children.ifEdit, 'String'),2);
        data.ifexpression = ifStr;
        bModified = 1;

    case 'modePopup'
        modeIdx = get(Children.modePopup, 'Value');
        data.mode = modeIdx;
        % => Update
        %         if data.mode == 2
        %             % clear elseif if mode = #ifdef
        %             data.elseifexpressions = '';
        %         end
        bModified = 1;

    case {'numInputEdit', 'numInputUpButton', 'numInputDownButton'}
        [numInputs,bModified] = ds_handle_editupdown(data.numinputs, [Children.numInputEdit ...
            Children.numInputUpButton Children.numInputDownButton], Children.(pageAction), Inf);
        data.numinputs = numInputs;

    otherwise
        error(['Invalid Control "' action '"']);

end

dlgdata.data = data;


%--------------------------------------------------------------------------
% FcnUpdateParameterPage updates the controls of the parameter tab
%
% INPUT ARGUMENTS
%   dlgdata     dialog data
%   dlgfig      figure handle of dialog
%   pageNum     page Number
%
% OUTPUT ARGUMENTS
%   dlgdata     modified dialog data
%--------------------------------------------------------------------------
function dlgdata = FcnUpdateParameterPage(dlgfig,dlgdata,pageNum)

Children = dlgdata.pageData{pageNum}.children;
data = dlgdata.data;

% enable/disable [-] Button. Ususally this is handled in
% ds_handle_editupdown, but this function is not called
% when the dialog is opened.
if data.numinputs == 1
    enableDown = 'off';
else
    enableDown = 'on';
end

% disable/enable elseif Button if #ifdef is used/ not used
if data.mode == 2
    data.elseifexpressions = '';
    enableElse = 'off';
else
    enableElse = 'on';
end

numInputDownButtonCtrlStatus = struct('enable', 'on');
numInputEditCtrlStatus = struct('enable', 'on');
showElseCheckboxCtrlStatus = struct('enable', 'on');
elseIfEditCtrlStatus = struct('enable', 'on');
ifEditCtrlStatus = struct('enable', 'on');
modePopupCtrlStatus = struct('enable', 'on', ...
    'string', {{'#if' '#ifdef' '#if defined'}}, ...
    'value', 1);

numInputDownButtonCtrlStatus.enable = enableDown;
numInputEditCtrlStatus.string = data.numinputs;
showElseCheckboxCtrlStatus.value = data.showelse;
% make string single-line, because edit control can not have multi-line text
elseIfEditCtrlStatus.string = strrep(data.elseifexpressions, char(10),' ');
elseIfEditCtrlStatus.enable = enableElse;
ifEditCtrlStatus.string = data.ifexpression;
modePopupCtrlStatus.value = data.mode;

dlgdata.data = data;

ctrlsList = {
    'numInputDownButton';
    'numInputEdit';
    'showElseCheckbox';
    'elseIfEdit';
    'ifEdit';
    'modePopup'};
for ctrlsNo = 1:length(ctrlsList)
    ctrl = Children.(ctrlsList{ctrlsNo});
    UserData = get(ctrl, 'UserData');
    UserData.ctrlStatus = eval([ctrlsList{ctrlsNo} 'CtrlStatus']);
    set(ctrl, 'UserData', UserData);
end
TLSetCtrlsStatus(dlgfig, Children, ctrlsList);
